06f9fb
@@ -98,7 +98,7 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 	 * Late binding entry set.
 	 */
 	@Nullable
-	private Set<Map.Entry<K, V>> entrySet;
+	private volatile Set<Map.Entry<K, V>> entrySet;
 
 
 	/**
@@ -167,8 +167,8 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 	 * @param referenceType the reference type used for entries (soft or weak)
 	 */
 	@SuppressWarnings("unchecked")
-	public ConcurrentReferenceHashMap(int initialCapacity, float loadFactor, int concurrencyLevel,
-			ReferenceType referenceType) {
+	public ConcurrentReferenceHashMap(
+			int initialCapacity, float loadFactor, int concurrencyLevel, ReferenceType referenceType) {
 
 		Assert.isTrue(initialCapacity >= 0, "Initial capacity must not be negative");
 		Assert.isTrue(loadFactor > 0f, "Load factor must be positive");
@@ -215,7 +215,7 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 	 * @return the resulting hash code
 	 */
 	protected int getHash(@Nullable Object o) {
-		int hash = o == null ? 0 : o.hashCode();
+		int hash = (o != null ? o.hashCode() : 0);
 		hash += (hash << 15) ^ 0xffffcd7d;
 		hash ^= (hash >>> 10);
 		hash += (hash << 3);
@@ -247,8 +247,8 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 
 	@Nullable
 	private Entry<K, V> getEntryIfAvailable(@Nullable Object key) {
-		Reference<K, V> reference = getReference(key, Restructure.WHEN_NECESSARY);
-		return (reference != null ? reference.get() : null);
+		Reference<K, V> ref = getReference(key, Restructure.WHEN_NECESSARY);
+		return (ref != null ? ref.get() : null);
 	}
 
 	/**
@@ -281,7 +281,7 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 		return doTask(key, new Task<V>(TaskOption.RESTRUCTURE_BEFORE, TaskOption.RESIZE) {
 			@Override
 			@Nullable
-			protected V execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry, @Nullable Entries entries) {
+			protected V execute(@Nullable Reference<K, V> ref, @Nullable Entry<K, V> entry, @Nullable Entries entries) {
 				if (entry != null) {
 					V oldValue = entry.getValue();
 					if (overwriteExisting) {
@@ -302,10 +302,10 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 		return doTask(key, new Task<V>(TaskOption.RESTRUCTURE_AFTER, TaskOption.SKIP_IF_EMPTY) {
 			@Override
 			@Nullable
-			protected V execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
+			protected V execute(@Nullable Reference<K, V> ref, @Nullable Entry<K, V> entry) {
 				if (entry != null) {
-					if (reference != null) {
-						reference.release();
+					if (ref != null) {
+						ref.release();
 					}
 					return entry.value;
 				}
@@ -318,10 +318,10 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 	public boolean remove(Object key, final Object value) {
 		Boolean result = doTask(key, new Task<Boolean>(TaskOption.RESTRUCTURE_AFTER, TaskOption.SKIP_IF_EMPTY) {
 			@Override
-			protected Boolean execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
+			protected Boolean execute(@Nullable Reference<K, V> ref, @Nullable Entry<K, V> entry) {
 				if (entry != null && ObjectUtils.nullSafeEquals(entry.getValue(), value)) {
-					if (reference != null) {
-						reference.release();
+					if (ref != null) {
+						ref.release();
 					}
 					return true;
 				}
@@ -335,7 +335,7 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 	public boolean replace(K key, final V oldValue, final V newValue) {
 		Boolean result = doTask(key, new Task<Boolean>(TaskOption.RESTRUCTURE_BEFORE, TaskOption.SKIP_IF_EMPTY) {
 			@Override
-			protected Boolean execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
+			protected Boolean execute(@Nullable Reference<K, V> ref, @Nullable Entry<K, V> entry) {
 				if (entry != null && ObjectUtils.nullSafeEquals(entry.getValue(), oldValue)) {
 					entry.setValue(newValue);
 					return true;
@@ -352,7 +352,7 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 		return doTask(key, new Task<V>(TaskOption.RESTRUCTURE_BEFORE, TaskOption.SKIP_IF_EMPTY) {
 			@Override
 			@Nullable
-			protected V execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
+			protected V execute(@Nullable Reference<K, V> ref, @Nullable Entry<K, V> entry) {
 				if (entry != null) {
 					V oldValue = entry.getValue();
 					entry.setValue(value);
@@ -393,11 +393,23 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 	}
 
 	@Override
-	public Set<java.util.Map.Entry<K, V>> entrySet() {
-		if (this.entrySet == null) {
-			this.entrySet = new EntrySet();
+	public boolean isEmpty() {
+		for (Segment segment : this.segments) {
+			if (segment.getCount() > 0) {
+				return false;
+			}
 		}
-		return this.entrySet;
+		return true;
+	}
+
+	@Override
+	public Set<Map.Entry<K, V>> entrySet() {
+		Set<Map.Entry<K, V>> entrySet = this.entrySet;
+		if (entrySet == null) {
+			entrySet = new EntrySet();
+			this.entrySet = entrySet;
+		}
+		return entrySet;
 	}
 
 	@Nullable
@@ -512,8 +524,8 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 			try {
 				final int index = getIndex(hash, this.references);
 				final Reference<K, V> head = this.references[index];
-				Reference<K, V> reference = findInChain(head, key, hash);
-				Entry<K, V> entry = (reference != null ? reference.get() : null);
+				Reference<K, V> ref = findInChain(head, key, hash);
+				Entry<K, V> entry = (ref != null ? ref.get() : null);
 				Entries entries = new Entries() {
 					@Override
 					public void add(@Nullable V value) {
@@ -524,7 +536,7 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 						Segment.this.count++;
 					}
 				};
-				return task.execute(reference, entry, entries);
+				return task.execute(ref, entry, entries);
 			}
 			finally {
 				unlock();
@@ -559,19 +571,18 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 		 * @param allowResize if resizing is permitted
 		 */
 		protected final void restructureIfNecessary(boolean allowResize) {
-			boolean needsResize = ((this.count > 0) && (this.count >= this.resizeThreshold));
-			Reference<K, V> reference = this.referenceManager.pollForPurge();
-			if ((reference != null) || (needsResize && allowResize)) {
+			boolean needsResize = (this.count > 0 && this.count >= this.resizeThreshold);
+			Reference<K, V> ref = this.referenceManager.pollForPurge();
+			if (ref != null || (needsResize && allowResize)) {
 				lock();
 				try {
 					int countAfterRestructure = this.count;
-
 					Set<Reference<K, V>> toPurge = Collections.emptySet();
-					if (reference != null) {
+					if (ref != null) {
 						toPurge = new HashSet<>();
-						while (reference != null) {
-							toPurge.add(reference);
-							reference = this.referenceManager.pollForPurge();
+						while (ref != null) {
+							toPurge.add(ref);
+							ref = this.referenceManager.pollForPurge();
 						}
 					}
 					countAfterRestructure -= toPurge.size();
@@ -587,24 +598,25 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 					}
 
 					// Either create a new table or reuse the existing one
-					Reference<K, V>[] restructured = (resizing ? createReferenceArray(restructureSize) : this.references);
+					Reference<K, V>[] restructured =
+							(resizing ? createReferenceArray(restructureSize) : this.references);
 
 					// Restructure
 					for (int i = 0; i < this.references.length; i++) {
-						reference = this.references[i];
+						ref = this.references[i];
 						if (!resizing) {
 							restructured[i] = null;
 						}
-						while (reference != null) {
-							if (!toPurge.contains(reference)) {
-								Entry<K, V> entry = reference.get();
+						while (ref != null) {
+							if (!toPurge.contains(ref)) {
+								Entry<K, V> entry = ref.get();
 								if (entry != null) {
-									int index = getIndex(reference.getHash(), restructured);
+									int index = getIndex(ref.getHash(), restructured);
 									restructured[index] = this.referenceManager.createReference(
-											entry, reference.getHash(), restructured[index]);
+											entry, ref.getHash(), restructured[index]);
 								}
 							}
-							reference = reference.getNext();
+							ref = ref.getNext();
 						}
 					}
 
@@ -622,8 +634,8 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 		}
 
 		@Nullable
-		private Reference<K, V> findInChain(Reference<K, V> reference, @Nullable Object key, int hash) {
-			Reference<K, V> currRef = reference;
+		private Reference<K, V> findInChain(Reference<K, V> ref, @Nullable Object key, int hash) {
+			Reference<K, V> currRef = ref;
 			while (currRef != null) {
 				if (currRef.getHash() == hash) {
 					Entry<K, V> entry = currRef.get();
@@ -667,7 +679,6 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 	/**
 	 * A reference to an {@link Entry} contained in the map. Implementations are usually
 	 * wrappers around specific Java reference implementations (e.g., {@link SoftReference}).
-	 *
 	 * @param <K> the key type
 	 * @param <V> the value type
 	 */
@@ -700,7 +711,6 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 
 	/**
 	 * A single map entry.
-	 *
 	 * @param <K> the key type
 	 * @param <V> the value type
 	 */
@@ -780,26 +790,26 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 
 		/**
 		 * Execute the task.
-		 * @param reference the found reference or {@code null}
-		 * @param entry the found entry or {@code null}
+		 * @param ref the found reference (or {@code null})
+		 * @param entry the found entry (or {@code null})
 		 * @param entries access to the underlying entries
 		 * @return the result of the task
 		 * @see #execute(Reference, Entry)
 		 */
 		@Nullable
-		protected T execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry, @Nullable Entries entries) {
-			return execute(reference, entry);
+		protected T execute(@Nullable Reference<K, V> ref, @Nullable Entry<K, V> entry, @Nullable Entries entries) {
+			return execute(ref, entry);
 		}
 
 		/**
 		 * Convenience method that can be used for tasks that do not need access to {@link Entries}.
-		 * @param reference the found reference or {@code null}
-		 * @param entry the found entry or {@code null}
+		 * @param ref the found reference (or {@code null})
+		 * @param entry the found entry (or {@code null})
 		 * @return the result of the task
 		 * @see #execute(Reference, Entry, Entries)
 		 */
 		@Nullable
-		protected T execute(@Nullable Reference<K, V> reference, @Nullable Entry<K, V> entry) {
+		protected T execute(@Nullable Reference<K, V> ref, @Nullable Entry<K, V> entry) {
 			return null;
 		}
 	}
@@ -840,9 +850,9 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 		@Override
 		public boolean contains(@Nullable Object o) {
 			if (o instanceof Map.Entry<?, ?>) {
-				Map.Entry<?, ?> entry = (java.util.Map.Entry<?, ?>) o;
-				Reference<K, V> reference = ConcurrentReferenceHashMap.this.getReference(entry.getKey(), Restructure.NEVER);
-				Entry<K, V> otherEntry = (reference != null ? reference.get() : null);
+				Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
+				Reference<K, V> ref = ConcurrentReferenceHashMap.this.getReference(entry.getKey(), Restructure.NEVER);
+				Entry<K, V> otherEntry = (ref != null ? ref.get() : null);
 				if (otherEntry != null) {
 					return ObjectUtils.nullSafeEquals(otherEntry.getValue(), otherEntry.getValue());
 				}
@@ -1003,7 +1013,7 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 
 
 	/**
-	 * Internal {@link Reference} implementation for {@link SoftReference Reference} implementation for {@link SoftReferences}.
+	 * Internal {@link Reference} implementation for {@link SoftReference SoftReferences}.
 	 */
 	private static final class SoftEntryReference<K, V> extends SoftReference<Entry<K, V>> implements Reference<K, V> {
 
@@ -1040,7 +1050,7 @@
public class ConcurrentReferenceHashMap<K, V> extends AbstractMap<K, V> implemen
 
 
 	/**
-	 * Internal {@link Reference} implementation for {@link WeakReference Reference} implementation for {@link WeakReferences}.
+	 * Internal {@link Reference} implementation for {@link WeakReference WeakReferences}.
 	 */
 	private static final class WeakEntryReference<K, V> extends WeakReference<Entry<K, V>> implements Reference<K, V> {
 
